{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "111bce49",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import math\n",
    "import numpy as np\n",
    "from numpy.linalg import norm\n",
    "import pinocchio as pin\n",
    "import example_robot_data as robex\n",
    "from scipy.optimize import fmin_bfgs\n",
    "import matplotlib.pylab as plt; plt.ion()\n",
    "\n",
    "import sys\n",
    "sys.path.append(\"/home/ydw/workspaces/AGI/arms/tps_robotics_ens_2024\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "5ebddc3e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/dw/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/pinocchio/__init__.py\n"
     ]
    }
   ],
   "source": [
    "import pinocchio\n",
    "print(pinocchio.__file__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5a8b3fde",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/dw/workspaces/fangnuo/avp_teleoperate/assets/arm_description7/urdf/arm_description7.urdf\n"
     ]
    }
   ],
   "source": [
    "import pinocchio\n",
    "from pinocchio.robot_wrapper import RobotWrapper\n",
    "from pathlib import Path\n",
    "import os\n",
    "\n",
    "\n",
    "package_dirs = \"/home/dw/workspaces/fangnuo/avp_teleoperate/assets\"\n",
    "urdf_path = str(package_dirs) + \"/arm_description7/urdf/arm_description7.urdf\"\n",
    "print(urdf_path)\n",
    "robot = RobotWrapper.BuildFromURDF(str(urdf_path), package_dirs=str(package_dirs))\n",
    "reduced_robot = robot\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "9f661c35",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Nb joints = 13 (nq=12,nv=12)\n",
      "  Joint 0 universe: parent=0\n",
      "  Joint 1 L_shoulder_yaw: parent=0\n",
      "  Joint 2 L_shoulder_pitch: parent=1\n",
      "  Joint 3 L_elbow: parent=2\n",
      "  Joint 4 L_wrist_roll: parent=3\n",
      "  Joint 5 L_wrist_pitch: parent=4\n",
      "  Joint 6 L_wrist_end: parent=5\n",
      "  Joint 7 R_shoulder_yaw: parent=0\n",
      "  Joint 8 R_shoulder_pitch: parent=7\n",
      "  Joint 9 R_elbow: parent=8\n",
      "  Joint 10 R_wrist_roll: parent=9\n",
      "  Joint 11 R_wrist_pitch: parent=10\n",
      "  Joint 12 R_wrist_end: parent=11\n",
      "\n",
      "[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n"
     ]
    }
   ],
   "source": [
    "print(robot.model)\n",
    "print(robot.q0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "72de0679",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pinocchio.pinocchio_pywrap_default.StdVec_StdString'>\n",
      "L_shoulder_yaw\n",
      "0 universe\n",
      "1 L_shoulder_yaw\n",
      "2 L_shoulder_pitch\n",
      "3 L_elbow\n",
      "4 L_wrist_roll\n",
      "5 L_wrist_pitch\n",
      "6 L_wrist_end\n",
      "7 R_shoulder_yaw\n",
      "8 R_shoulder_pitch\n",
      "9 R_elbow\n",
      "10 R_wrist_roll\n",
      "11 R_wrist_pitch\n",
      "12 R_wrist_end\n"
     ]
    }
   ],
   "source": [
    "print(type(robot.model.names))\n",
    "print(robot.model.names[1])\n",
    "for i, n in enumerate(robot.model.names):\n",
    "    print(i, n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "b115bf2a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "robot.index('L_wrist_end')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "6f44ea17",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "universe -> attached to joint # 0\n",
      "base_link -> attached to joint # 0\n",
      "JR1 -> attached to joint # 0\n",
      "Link_R1 -> attached to joint # 0\n",
      "JR2 -> attached to joint # 0\n",
      "Link_R2 -> attached to joint # 0\n",
      "JR3 -> attached to joint # 0\n",
      "Link_R3 -> attached to joint # 0\n",
      "JR4 -> attached to joint # 0\n",
      "Link_R4 -> attached to joint # 0\n",
      "L_shoulder_yaw -> attached to joint # 1\n",
      "Link_L_shoulder_yaw -> attached to joint # 1\n",
      "L_shoulder_pitch -> attached to joint # 2\n",
      "Link_L_shoulder_pitch -> attached to joint # 2\n",
      "L_elbow -> attached to joint # 3\n",
      "Link_L_elbow -> attached to joint # 3\n",
      "L_wrist_roll -> attached to joint # 4\n",
      "Link_L_wrist_roll -> attached to joint # 4\n",
      "L_wrist_pitch -> attached to joint # 5\n",
      "Link_L_wrist_pitch -> attached to joint # 5\n",
      "L_wrist_end -> attached to joint # 6\n",
      "Link_L_wrist_end -> attached to joint # 6\n",
      "L_Grip -> attached to joint # 6\n",
      "Link_L_Grip -> attached to joint # 6\n",
      "R_shoulder_yaw -> attached to joint # 7\n",
      "Link_R_shoulder_yaw -> attached to joint # 7\n",
      "R_shoulder_pitch -> attached to joint # 8\n",
      "Link_R_shoulder_pitch -> attached to joint # 8\n",
      "R_elbow -> attached to joint # 9\n",
      "Link_R_elbow -> attached to joint # 9\n",
      "R_wrist_roll -> attached to joint # 10\n",
      "Link_R_wrist_roll -> attached to joint # 10\n",
      "R_wrist_pitch -> attached to joint # 11\n",
      "Link_R_wrist_pitch -> attached to joint # 11\n",
      "R_wrist_end -> attached to joint # 12\n",
      "Link_R_wrist_end -> attached to joint # 12\n",
      "R_Grip -> attached to joint # 12\n",
      "Link_R_Grip -> attached to joint # 12\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/tmp/ipykernel_2086178/1851212685.py:2: UserWarning: Deprecated member. Use Frame.parentJoint instead.\n",
      "  print(f.name, '-> attached to joint #', f.parent)\n"
     ]
    }
   ],
   "source": [
    "for f in robot.model.frames:\n",
    "    print(f.name, '-> attached to joint #', f.parent)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "a29a82ac",
   "metadata": {},
   "outputs": [],
   "source": [
    "# from utils.meshcat_viewer_wrapper import MeshcatVisualizer, colors  # noqa: E402\n",
    "from pinocchio.visualize import MeshcatVisualizer\n",
    "viz = MeshcatVisualizer(reduced_robot.model, reduced_robot.collision_model, reduced_robot.visual_model)\n",
    "# viz.viewer.jupyter_cell()\n",
    "# viz.display(reduced_robot.q0)\n",
    "\n",
    "\n",
    "# boxID = 'world/box';   viz.addBox(boxID,[.1,.1,.1],[1,1,0,1])\n",
    "# viz.applyConfiguration(boxID,[1,0,.0,1,0,0,0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "39dd9916",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "JointModelRZ L_shoulder_yaw\n",
      "JointModelRZ L_shoulder_pitch\n",
      "JointModelRZ L_elbow\n",
      "JointModelRevoluteUnaligned L_wrist_roll\n",
      "JointModelRZ L_wrist_pitch\n",
      "JointModelRevoluteUnaligned L_wrist_end\n",
      "JointModelRZ R_shoulder_yaw\n",
      "JointModelRZ R_shoulder_pitch\n",
      "JointModelRZ R_elbow\n",
      "JointModelRevoluteUnaligned R_wrist_roll\n",
      "JointModelRZ R_wrist_pitch\n",
      "JointModelRevoluteUnaligned R_wrist_end\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "337eb4e8a93247a0ac375fc1111eddca",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "VBox(children=(FloatSlider(value=0.0, description='L_shoulder_yaw', layout=Layout(width='500px'), max=2.687, m…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "ename": "AttributeError",
     "evalue": "'MeshcatVisualizer' object has no attribute 'display_collisions'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[0;34m(self, msg)\u001b[0m\n\u001b[1;32m    771\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[1;32m    772\u001b[0m             _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m--> 773\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[1;32m    776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[0;34m(self, sync_data)\u001b[0m\n\u001b[1;32m    645\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[1;32m    647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[1;32m    648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[1;32m    649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[0;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[1;32m    651\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[1;32m    652\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[0;34m(self, typ, value, traceback)\u001b[0m\n\u001b[1;32m    140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    141\u001b[0m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 142\u001b[0m         \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    143\u001b[0m     \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m    144\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[1;32m   1509\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[0;32m-> 1510\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m    698\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[1;32m    699\u001b[0m         \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[1;32m    700\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[0;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m   1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1524\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1525\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m   1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1566\u001b[0m     c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[22], line 45\u001b[0m, in \u001b[0;36mupdate_robot\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m     43\u001b[0m pin\u001b[38;5;241m.\u001b[39mforwardKinematics(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[1;32m     44\u001b[0m pin\u001b[38;5;241m.\u001b[39mupdateFramePlacements(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata)\n\u001b[0;32m---> 45\u001b[0m \u001b[43mviz\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay\u001b[49m\u001b[43m(\u001b[49m\u001b[43mq\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/pinocchio/visualize/meshcat_visualizer.py:977\u001b[0m, in \u001b[0;36mMeshcatVisualizer.display\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m    974\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m q \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    975\u001b[0m     pin\u001b[38;5;241m.\u001b[39mforwardKinematics(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[0;32m--> 977\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay_collisions\u001b[49m:\n\u001b[1;32m    978\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mupdatePlacements(pin\u001b[38;5;241m.\u001b[39mGeometryType\u001b[38;5;241m.\u001b[39mCOLLISION)\n\u001b[1;32m    980\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdisplay_visuals:\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'MeshcatVisualizer' object has no attribute 'display_collisions'"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'MeshcatVisualizer' object has no attribute 'display_collisions'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[0;34m(self, msg)\u001b[0m\n\u001b[1;32m    771\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[1;32m    772\u001b[0m             _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m--> 773\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[1;32m    776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[0;34m(self, sync_data)\u001b[0m\n\u001b[1;32m    645\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[1;32m    647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[1;32m    648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[1;32m    649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[0;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[1;32m    651\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[1;32m    652\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[0;34m(self, typ, value, traceback)\u001b[0m\n\u001b[1;32m    140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    141\u001b[0m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 142\u001b[0m         \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    143\u001b[0m     \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m    144\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[1;32m   1509\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[0;32m-> 1510\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m    698\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[1;32m    699\u001b[0m         \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[1;32m    700\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[0;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m   1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1524\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1525\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m   1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1566\u001b[0m     c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[22], line 45\u001b[0m, in \u001b[0;36mupdate_robot\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m     43\u001b[0m pin\u001b[38;5;241m.\u001b[39mforwardKinematics(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[1;32m     44\u001b[0m pin\u001b[38;5;241m.\u001b[39mupdateFramePlacements(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata)\n\u001b[0;32m---> 45\u001b[0m \u001b[43mviz\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay\u001b[49m\u001b[43m(\u001b[49m\u001b[43mq\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/pinocchio/visualize/meshcat_visualizer.py:977\u001b[0m, in \u001b[0;36mMeshcatVisualizer.display\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m    974\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m q \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    975\u001b[0m     pin\u001b[38;5;241m.\u001b[39mforwardKinematics(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[0;32m--> 977\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay_collisions\u001b[49m:\n\u001b[1;32m    978\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mupdatePlacements(pin\u001b[38;5;241m.\u001b[39mGeometryType\u001b[38;5;241m.\u001b[39mCOLLISION)\n\u001b[1;32m    980\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdisplay_visuals:\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'MeshcatVisualizer' object has no attribute 'display_collisions'"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'MeshcatVisualizer' object has no attribute 'display_collisions'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[0;34m(self, msg)\u001b[0m\n\u001b[1;32m    771\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[1;32m    772\u001b[0m             _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m--> 773\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[1;32m    776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[0;34m(self, sync_data)\u001b[0m\n\u001b[1;32m    645\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[1;32m    647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[1;32m    648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[1;32m    649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[0;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[1;32m    651\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[1;32m    652\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[0;34m(self, typ, value, traceback)\u001b[0m\n\u001b[1;32m    140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    141\u001b[0m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 142\u001b[0m         \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    143\u001b[0m     \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m    144\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[1;32m   1509\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[0;32m-> 1510\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m    698\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[1;32m    699\u001b[0m         \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[1;32m    700\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[0;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m   1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1524\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1525\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m   1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1566\u001b[0m     c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[22], line 45\u001b[0m, in \u001b[0;36mupdate_robot\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m     43\u001b[0m pin\u001b[38;5;241m.\u001b[39mforwardKinematics(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[1;32m     44\u001b[0m pin\u001b[38;5;241m.\u001b[39mupdateFramePlacements(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata)\n\u001b[0;32m---> 45\u001b[0m \u001b[43mviz\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay\u001b[49m\u001b[43m(\u001b[49m\u001b[43mq\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/pinocchio/visualize/meshcat_visualizer.py:977\u001b[0m, in \u001b[0;36mMeshcatVisualizer.display\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m    974\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m q \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    975\u001b[0m     pin\u001b[38;5;241m.\u001b[39mforwardKinematics(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[0;32m--> 977\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay_collisions\u001b[49m:\n\u001b[1;32m    978\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mupdatePlacements(pin\u001b[38;5;241m.\u001b[39mGeometryType\u001b[38;5;241m.\u001b[39mCOLLISION)\n\u001b[1;32m    980\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdisplay_visuals:\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'MeshcatVisualizer' object has no attribute 'display_collisions'"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'MeshcatVisualizer' object has no attribute 'display_collisions'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[0;34m(self, msg)\u001b[0m\n\u001b[1;32m    771\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[1;32m    772\u001b[0m             _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m--> 773\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[1;32m    776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[0;34m(self, sync_data)\u001b[0m\n\u001b[1;32m    645\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[1;32m    647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[1;32m    648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[1;32m    649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[0;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[1;32m    651\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[1;32m    652\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[0;34m(self, typ, value, traceback)\u001b[0m\n\u001b[1;32m    140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    141\u001b[0m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 142\u001b[0m         \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    143\u001b[0m     \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m    144\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[1;32m   1509\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[0;32m-> 1510\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m    698\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[1;32m    699\u001b[0m         \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[1;32m    700\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[0;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m   1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1524\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1525\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m   1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1566\u001b[0m     c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[22], line 45\u001b[0m, in \u001b[0;36mupdate_robot\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m     43\u001b[0m pin\u001b[38;5;241m.\u001b[39mforwardKinematics(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[1;32m     44\u001b[0m pin\u001b[38;5;241m.\u001b[39mupdateFramePlacements(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata)\n\u001b[0;32m---> 45\u001b[0m \u001b[43mviz\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay\u001b[49m\u001b[43m(\u001b[49m\u001b[43mq\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/pinocchio/visualize/meshcat_visualizer.py:977\u001b[0m, in \u001b[0;36mMeshcatVisualizer.display\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m    974\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m q \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    975\u001b[0m     pin\u001b[38;5;241m.\u001b[39mforwardKinematics(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[0;32m--> 977\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay_collisions\u001b[49m:\n\u001b[1;32m    978\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mupdatePlacements(pin\u001b[38;5;241m.\u001b[39mGeometryType\u001b[38;5;241m.\u001b[39mCOLLISION)\n\u001b[1;32m    980\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdisplay_visuals:\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'MeshcatVisualizer' object has no attribute 'display_collisions'"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'MeshcatVisualizer' object has no attribute 'display_collisions'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[0;34m(self, msg)\u001b[0m\n\u001b[1;32m    771\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[1;32m    772\u001b[0m             _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m--> 773\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[1;32m    776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[0;34m(self, sync_data)\u001b[0m\n\u001b[1;32m    645\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[1;32m    647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[1;32m    648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[1;32m    649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[0;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[1;32m    651\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[1;32m    652\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[0;34m(self, typ, value, traceback)\u001b[0m\n\u001b[1;32m    140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    141\u001b[0m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 142\u001b[0m         \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    143\u001b[0m     \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m    144\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[1;32m   1509\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[0;32m-> 1510\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m    698\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[1;32m    699\u001b[0m         \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[1;32m    700\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[0;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m   1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1524\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1525\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m   1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1566\u001b[0m     c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[22], line 45\u001b[0m, in \u001b[0;36mupdate_robot\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m     43\u001b[0m pin\u001b[38;5;241m.\u001b[39mforwardKinematics(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[1;32m     44\u001b[0m pin\u001b[38;5;241m.\u001b[39mupdateFramePlacements(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata)\n\u001b[0;32m---> 45\u001b[0m \u001b[43mviz\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay\u001b[49m\u001b[43m(\u001b[49m\u001b[43mq\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/pinocchio/visualize/meshcat_visualizer.py:977\u001b[0m, in \u001b[0;36mMeshcatVisualizer.display\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m    974\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m q \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    975\u001b[0m     pin\u001b[38;5;241m.\u001b[39mforwardKinematics(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[0;32m--> 977\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay_collisions\u001b[49m:\n\u001b[1;32m    978\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mupdatePlacements(pin\u001b[38;5;241m.\u001b[39mGeometryType\u001b[38;5;241m.\u001b[39mCOLLISION)\n\u001b[1;32m    980\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdisplay_visuals:\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'MeshcatVisualizer' object has no attribute 'display_collisions'"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'MeshcatVisualizer' object has no attribute 'display_collisions'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:773\u001b[0m, in \u001b[0;36mWidget._handle_msg\u001b[0;34m(self, msg)\u001b[0m\n\u001b[1;32m    771\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01min\u001b[39;00m data:\n\u001b[1;32m    772\u001b[0m             _put_buffers(state, data[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffer_paths\u001b[39m\u001b[38;5;124m'\u001b[39m], msg[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mbuffers\u001b[39m\u001b[38;5;124m'\u001b[39m])\n\u001b[0;32m--> 773\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mset_state\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstate\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    775\u001b[0m \u001b[38;5;66;03m# Handle a state request.\u001b[39;00m\n\u001b[1;32m    776\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m method \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mrequest_state\u001b[39m\u001b[38;5;124m'\u001b[39m:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:650\u001b[0m, in \u001b[0;36mWidget.set_state\u001b[0;34m(self, sync_data)\u001b[0m\n\u001b[1;32m    645\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_send(msg, buffers\u001b[38;5;241m=\u001b[39mecho_buffers)\n\u001b[1;32m    647\u001b[0m \u001b[38;5;66;03m# The order of these context managers is important. Properties must\u001b[39;00m\n\u001b[1;32m    648\u001b[0m \u001b[38;5;66;03m# be locked when the hold_trait_notification context manager is\u001b[39;00m\n\u001b[1;32m    649\u001b[0m \u001b[38;5;66;03m# released and notifications are fired.\u001b[39;00m\n\u001b[0;32m--> 650\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_lock_property(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39msync_data), \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhold_trait_notifications():\n\u001b[1;32m    651\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m sync_data:\n\u001b[1;32m    652\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys:\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/contextlib.py:142\u001b[0m, in \u001b[0;36m_GeneratorContextManager.__exit__\u001b[0;34m(self, typ, value, traceback)\u001b[0m\n\u001b[1;32m    140\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m typ \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    141\u001b[0m     \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 142\u001b[0m         \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgen\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    143\u001b[0m     \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mStopIteration\u001b[39;00m:\n\u001b[1;32m    144\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1510\u001b[0m, in \u001b[0;36mHasTraits.hold_trait_notifications\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m   1508\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m changes \u001b[38;5;129;01min\u001b[39;00m cache\u001b[38;5;241m.\u001b[39mvalues():\n\u001b[1;32m   1509\u001b[0m     \u001b[38;5;28;01mfor\u001b[39;00m change \u001b[38;5;129;01min\u001b[39;00m changes:\n\u001b[0;32m-> 1510\u001b[0m         \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/ipywidgets/widgets/widget.py:701\u001b[0m, in \u001b[0;36mWidget.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m    698\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m name \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mkeys \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_should_send_property(name, \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, name)):\n\u001b[1;32m    699\u001b[0m         \u001b[38;5;66;03m# Send new state to front-end\u001b[39;00m\n\u001b[1;32m    700\u001b[0m         \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39msend_state(key\u001b[38;5;241m=\u001b[39mname)\n\u001b[0;32m--> 701\u001b[0m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnotify_change\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1525\u001b[0m, in \u001b[0;36mHasTraits.notify_change\u001b[0;34m(self, change)\u001b[0m\n\u001b[1;32m   1523\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mnotify_change\u001b[39m(\u001b[38;5;28mself\u001b[39m, change: Bunch) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1524\u001b[0m \u001b[38;5;250m    \u001b[39m\u001b[38;5;124;03m\"\"\"Notify observers of a change event\"\"\"\u001b[39;00m\n\u001b[0;32m-> 1525\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_notify_observers\u001b[49m\u001b[43m(\u001b[49m\u001b[43mchange\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/traitlets/traitlets.py:1568\u001b[0m, in \u001b[0;36mHasTraits._notify_observers\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m   1565\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(c, EventHandler) \u001b[38;5;129;01mand\u001b[39;00m c\u001b[38;5;241m.\u001b[39mname \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m   1566\u001b[0m     c \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(\u001b[38;5;28mself\u001b[39m, c\u001b[38;5;241m.\u001b[39mname)\n\u001b[0;32m-> 1568\u001b[0m \u001b[43mc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mevent\u001b[49m\u001b[43m)\u001b[49m\n",
      "Cell \u001b[0;32mIn[22], line 45\u001b[0m, in \u001b[0;36mupdate_robot\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m     43\u001b[0m pin\u001b[38;5;241m.\u001b[39mforwardKinematics(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[1;32m     44\u001b[0m pin\u001b[38;5;241m.\u001b[39mupdateFramePlacements(robot\u001b[38;5;241m.\u001b[39mmodel, robot\u001b[38;5;241m.\u001b[39mdata)\n\u001b[0;32m---> 45\u001b[0m \u001b[43mviz\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay\u001b[49m\u001b[43m(\u001b[49m\u001b[43mq\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/miniconda3/envs/fangnuo-dev/lib/python3.10/site-packages/pinocchio/visualize/meshcat_visualizer.py:977\u001b[0m, in \u001b[0;36mMeshcatVisualizer.display\u001b[0;34m(self, q)\u001b[0m\n\u001b[1;32m    974\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m q \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    975\u001b[0m     pin\u001b[38;5;241m.\u001b[39mforwardKinematics(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmodel, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdata, q)\n\u001b[0;32m--> 977\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdisplay_collisions\u001b[49m:\n\u001b[1;32m    978\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mupdatePlacements(pin\u001b[38;5;241m.\u001b[39mGeometryType\u001b[38;5;241m.\u001b[39mCOLLISION)\n\u001b[1;32m    980\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdisplay_visuals:\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'MeshcatVisualizer' object has no attribute 'display_collisions'"
     ]
    }
   ],
   "source": [
    "# 实现交互操作左手每个关节\n",
    "import ipywidgets as widgets\n",
    "from IPython.display import display\n",
    "\n",
    "# 获取可控关节名、上下界\n",
    "joint_names = []\n",
    "lower = []\n",
    "upper = []\n",
    "q_idx = 0  # 用于同步limit数组的下标\n",
    "for idx in range(1, robot.model.njoints):\n",
    "    \n",
    "    joint = robot.model.joints[idx]\n",
    "    print(joint.shortname(), robot.model.names[idx] )\n",
    "    if joint.nq > 0:\n",
    "        joint_names.append(robot.model.names[idx])\n",
    "        # 每个有自由度的joint，依次取nq个limit\n",
    "        lower.append(robot.model.lowerPositionLimit[q_idx])\n",
    "        upper.append(robot.model.upperPositionLimit[q_idx])\n",
    "        q_idx += joint.nq\n",
    "\n",
    "# 构建滑块\n",
    "sliders = []\n",
    "for i, name in enumerate(joint_names):\n",
    "    slider = widgets.FloatSlider(\n",
    "        value=0.0,\n",
    "        min=lower[i],\n",
    "        max=upper[i],\n",
    "        step=0.01,\n",
    "        description=name,\n",
    "        continuous_update=True,\n",
    "        orientation='horizontal',\n",
    "        readout=True,\n",
    "        readout_format='.2f',\n",
    "        style={'description_width': '200px'},\n",
    "        layout=widgets.Layout(width='500px')  # 这里设置滑块长度\n",
    "    )\n",
    "    sliders.append(slider)\n",
    "\n",
    "def update_robot(*args):\n",
    "    q = np.zeros(robot.model.nq)\n",
    "    for i, slider in enumerate(sliders):\n",
    "        q[i] = slider.value\n",
    "    pin.forwardKinematics(robot.model, robot.data, q)\n",
    "    pin.updateFramePlacements(robot.model, robot.data)\n",
    "    viz.display(q)\n",
    "    # 显示每个关节坐标系（可选，meshcat可用）\n",
    "    # for i, name in enumerate(joint_names):\n",
    "    #     frame_id = robot.model.getFrameId(name)\n",
    "    #     if frame_id != 0:\n",
    "    #         placement = robot.data.oMf[frame_id]\n",
    "    #         viz.viewer[\"/coordinate_systems/\"+name].set_object(pin.visualize.visualize.FrameVisual(placement, 0.05))\n",
    "\n",
    "for slider in sliders:\n",
    "    slider.observe(update_robot, names='value')\n",
    "\n",
    "display(widgets.VBox(sliders))\n",
    "# update_robot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "id": "8a1d757d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Add a red box in the viewer\n",
    "ballID = \"world/ball\"\n",
    "radius = 0.03\n",
    "viz.addSphere(ballID, radius, colors.red)\n",
    "\n",
    "# The viewer expect position and rotation, apppend the identity quaternion\n",
    "o_ball = np.array([0.4, 0, 0.8]) #[0.3, 0, 0.1]\n",
    "q_ball = o_ball.tolist() +  [1, 0, 0, 0]\n",
    "viz.applyConfiguration(ballID, q_ball)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "id": "805676c1",
   "metadata": {},
   "outputs": [],
   "source": [
    "robot.q0 # 表示所有自由度的零位取值\n",
    "# array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])\n",
    "\n",
    "q = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])\n",
    "viz.display(q)\n",
    "\n",
    "target = o_ball"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "id": "ba5f06c7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Current joint values: <pinocchio.pinocchio_pywrap.Data object at 0x609789cb08b0>\n"
     ]
    }
   ],
   "source": [
    "# 当前所有关节的取值\n",
    "print(f\"Current joint values: {robot.data}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "id": "4b2b06f6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "22"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "IDX_HAND = robot.model.getFrameId('Link_L_wrist_end')\n",
    "IDX_HAND"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b1f6c99d",
   "metadata": {},
   "source": [
    "关节的雅可比矩阵（Jacobian）是机器人学中的一个核心概念，用于描述机器人末端执行器的速度与各个关节速度之间的线性关系\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "id": "2e3a82cb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# FK and IK\n",
    "q = robot.q0.copy()\n",
    "viz.display(q)\n",
    "DT = 1e-2 # 10ms\n",
    "herr = [] # 记录手部到目标的误差\n",
    "\n",
    "for i in range(500):  # 进行5秒的积分\n",
    "\n",
    "    # Run the algorithms that outputs values in robot.data\n",
    "    pin.framesForwardKinematics(robot.model,robot.data,q)\n",
    "    pin.computeJointJacobians(robot.model,robot.data,q)\n",
    "\n",
    "    # Placement from world frame o to frame f oMgaze\n",
    "    oMhand = robot.data.oMf[IDX_HAND]\n",
    "\n",
    "    # 计算手部在世界坐标系下的雅可比矩阵（只取前三行，对应线速度部分）\n",
    "    # 雅可比矩阵描述了关节速度与末端线速度之间的线性关系\n",
    "    o_Jhand3 = pin.computeFrameJacobian(robot.model, robot.data, \\\n",
    "    q, IDX_HAND,pin.LOCAL_WORLD_ALIGNED)[:3,:]\n",
    " \n",
    "\n",
    "    # 计算当前末端位置与目标点之间的向量（误差）(x,y,z)(参照系是手部)\n",
    "    o_Hand2Target = oMhand.translation - target\n",
    "    # 在手部坐标系下的雅可比矩阵的逆矩阵，计算关节速度\n",
    "    vq = -np.linalg.pinv(o_Jhand3) @ o_Hand2Target\n",
    "    # 将关节速度积分，更新关节角度\n",
    "    q = pin.integrate(robot.model,q, vq * DT)\n",
    "    viz.display(q)\n",
    "    time.sleep(1e-3)\n",
    "\n",
    "    herr.append(o_Hand2Target) \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "58847817",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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5OQ4uzSXUVVVJY4fPy6OHz8uAIhXX31VHD9+3N79wssvvyw0Go348ssvxalTp8Tdd9/d4mOpAwcOFLt27RIpKSnixhtv5OO/V/iv//ovodFoxI8//ujwCHBtba29DY/1tVu1apX46aefRHZ2tjh58qT405/+JGQymfj++++FEDzG3anp03BC8Fh3lSeffFL8+OOP4vz58yI5OVksWLBAeHt723/netNxZljqxd58800xePBgoVKpxIQJE+yPYlPH7NmzRwBoNtx3331CCNujqatXrxYhISFCrVaL66+/Xpw6dcphHXV1dWLFihXC399fuLu7iwULFogLFy44YW96r5aOMQDx0Ucf2dvwWF+7Bx54wP7vQWBgoJg9e7Y9KAnBY9ydrgxLPNZdo7HfJKVSKcLCwsTtt98u0tPT7fN703GWhBCia89VEREREfUdvGeJiIiIqA0MS0RERERtYFgiIiIiagPDEhEREVEbGJaIiIiI2sCwRERERNQGhiUiIiKiNjAsEREREbWBYYmI+qSNGzfC19fXadu///77sWjRomteT2ZmJkJCQlBVVQWg+/frzjvvxKuvvtpt6ydyRQxLRNRrRERE4PXXX3d2Gb3Ks88+iz/84Q/w9vYGACxZsgRnz561z1+zZg3GjRvXZdt7/vnn8dJLL0Gv13fZOolcHcMSEbkUi8UCq9Xq7DJ6RH5+PrZv347f/OY39mnu7u4ICgrq8m2ZTCYAwJgxYxAREYEtW7Z0+TaIXBXDEhF1iNVqxd/+9jcMGzYMarUagwYNwksvvWSff+rUKdx4441wd3dHQEAAHnroIVRXV9vnN16W+t///V+EhoYiICAAf/jDH+w/0jNnzkRubi4ef/xxSJIESZIAXL7s9J///AejRo2CWq1Gbm4uKioqcO+998LPzw8eHh64+eabkZWV1al9ys/Px9KlS+Hv7w9PT09MmjQJhw4dQk5ODmQyGY4ePerQ/o033sDgwYPR+ErN9PR0zJ8/Hz4+PvD29sZ1112Hc+fOtbgtIQReeeUVDBkyBO7u7hg7diz+/e9/t1nf559/jrFjx2LgwIH2aU0vw23cuBEvvPACTpw4YT9mGzduBADodDo89NBDCAoKgo+PD2688UacOHHCvp7GM1IffvghhgwZArVabd+vhQsX4tNPP+3UsSTqyxiWiKhDVq1ahb/97W947rnncPr0aXzyyScIDg4GANTW1mLevHnw8/PDkSNH8K9//Qu7du3CihUrHNaxZ88enDt3Dnv27MGmTZuwceNG+4/7l19+iYEDB2Lt2rUoKChAQUGBfbna2lqsW7cO77//PtLT0xEUFIT7778fR48exfbt23Hw4EEIIXDLLbfYw1d7qqurccMNN+DSpUvYvn07Tpw4gaeffhpWqxURERGYM2cOPvroI4dlPvroI9x///2QJAkXL17E9ddfDzc3N/zwww84duwYHnjgAZjN5ha39+c//xkfffQR3nrrLaSnp+Pxxx/H8uXLsXfv3lZr/OmnnzBp0qRW5y9ZsgRPPvkkRo8ebT9mS5YsgRAC8+fPR2FhIXbs2IFjx45hwoQJmD17NsrLy+3L//LLL/j888/xxRdfIDU11T59ypQpOHz4MAwGQ4eOJVGfJ4iI2qHX64VarRbvvfdei/Pfffdd4efnJ6qrq+3TvvnmGyGTyURhYaEQQoj77rtPDB48WJjNZnubu+66SyxZssQ+PnjwYPHaa685rPujjz4SAERqaqp92tmzZwUA8fPPP9unlZaWCnd3d/H555/bl9NoNK3u0zvvvCO8vb1FWVlZi/M/++wz4efnJ+rr64UQQqSmpgpJkkR2drYQQohVq1aJyMhIYTQaW1z+vvvuE7feeqsQQojq6mrh5uYmDhw44NDmwQcfFHfffXerNY4dO1asXbvWYdqV+7V69WoxduxYhza7d+8WPj4+9tobDR06VLzzzjv25ZRKpSguLm623RMnTggAIicnp9XaiPoTnlkionZlZGTAYDBg9uzZrc4fO3YsPD097dNmzJgBq9WKzMxM+7TRo0dDLpfbx0NDQ1FcXNzu9lUqFcaMGeOwPYVCgalTp9qnBQQEYOTIkcjIyOjQPqWmpmL8+PHw9/dvcf6iRYugUCiwbds2AMCHH36IWbNmISIiwr78ddddB6VS2e62Tp8+jfr6etx0003w8vKyDx9//HGrl+0AoK6uDm5ubh3an6aOHTuG6upqBAQEOGwvOzvbYXuDBw9GYGBgs+Xd3d0B2M7oERGgcHYBRNT7Nf54tkYIYb/H6EpNp18ZLCRJ6tDN2u7u7g7rEQ331nSmjpbW2RaVSoWEhAR89NFHuP322/HJJ584PKnX3vJNNe7jN998gwEDBjjMU6vVrS6n1WpRUVHR4e003V5oaCh+/PHHZvOadjvQNNw21XiprqUgRdQf8cwSEbVr+PDhcHd3x+7du1ucP2rUKKSmpqKmpsY+7eeff4ZMJsOIESM6vB2VSgWLxdJuu1GjRsFsNuPQoUP2aWVlZTh79iyio6M7tK0xY8YgNTXV4R6eK/32t7/Frl27sGHDBphMJtx+++0Oy+/bt69D90g13ph+4cIFDBs2zGEIDw9vdbnx48fj9OnTba67pWM2YcIEFBYWQqFQNNueVqttt960tDQMHDiwQ22J+gOGJSJql5ubG5555hk8/fTT9ktHycnJ+OCDDwAA99xzD9zc3HDfffchLS0Ne/bswSOPPIKEhAT7TeAdERERgZ9++gkXL15EaWlpq+2GDx+OW2+9FYmJidi/fz9OnDiB5cuXY8CAAbj11ls7tK27774bISEhWLRoEX7++WecP38eX3zxBQ4ePGhvEx0djWnTpuGZZ57B3Xff7XA2acWKFdDr9Vi6dCmOHj2KrKwsbN682eGyYyNvb2889dRTePzxx7Fp0yacO3cOx48fx5tvvolNmza1WuPcuXNx8ODBNgNkREQEsrOzkZqaitLSUhgMBsyZMwdxcXFYtGgRvvvuO+Tk5ODAgQP485//3OwJv5bs27cP8fHx7bYj6i8YloioQ5577jk8+eSTeP755xEdHY0lS5bY7zfy8PDAd999h/LyckyePBl33nknZs+ejfXr13dqG2vXrkVOTg6GDh3a7iWgjz76CBMnTsSCBQsQFxcHIQR27NjRoXuIANsZme+//x5BQUG45ZZbEBsbi5dfftnhnioAePDBB2E0GvHAAw84TA8ICMAPP/xgf6pu4sSJeO+991rd/osvvojnn38e69atQ3R0NObOnYuvv/4akZGRrdZ4yy23QKlUYteuXa22ueOOOzBv3jzMmjULgYGB+PTTTyFJEnbs2IHrr78eDzzwAEaMGIGlS5ciJyen3fBaX1+Pbdu2ITExsc12RP2JJFq7+E9ERHjppZewdetWnDp1yinb37BhA7766it89913PbK9N998E1999RW+//77HtkekSvgDd5ERC2orq5GRkYG3njjDbz44otOq+Ohhx5CRUUFqqqq7K886U5KpRJvvPFGt2+HyJXwzBIRUQvuv/9+fPrpp1i0aBE++eSTZpfniKj/YFgiIiIiagNv8CYiIiJqA8MSERERURsYloiIiIjawLBERERE1AaGJSIiIqI2MCwRERERtYFhiYiIiKgNDEtEREREbfj/hy9F8ZpVx1kAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 误差可视化\n",
    "plt.plot(herr)\n",
    "plt.xlabel('control cycle (iter)')\n",
    "plt.ylabel('error (m)');"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "fangnuo-dev",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
